package com.niiwoo.civet.account.service.local.fundsFreeze;

import com.niiwoo.civet.account.dao.entity.AccountBase;
import com.niiwoo.civet.account.dao.entity.FundsFreezeOrder;
import com.niiwoo.civet.account.dao.entity.FundsUnfreezeOrder;
import com.niiwoo.civet.account.dao.mapper.AccountBaseMapperExt;
import com.niiwoo.civet.account.dao.mapper.FundsFreezeOrderMapperExt;
import com.niiwoo.civet.account.dto.request.FundsFreezeOrderApplyRequestDTO;
import com.niiwoo.civet.account.enums.FundsFreezeOrderStatusEnum;
import com.niiwoo.civet.account.enums.FundsUnfreezeDegreeEnum;
import com.niiwoo.civet.account.service.local.AccountService;
import com.niiwoo.tripod.base.utils.DateUtils;
import com.niiwoo.tripod.lanmao.component.LanMaoSequence;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author Jaylin
 * @Date 2018-04-24
 * @Descript 资金冻结订单服务
 */
@Service
public class FundsFreezeOrderService {

    @Autowired
    private FundsFreezeOrderMapperExt freezeOrderMapperExt;
    @Autowired
    private SnowflakeIdWorker idWorker;
    @Autowired
    private LanMaoSequence lanMaoSequence;
    @Autowired
    private AccountService accountService;


    /**
     * 申请资金冻结订单
     *
     * @param applyRequestDTO
     * @return
     */
    @Transactional
    public FundsFreezeOrder applyFundsFreezeOrder(FundsFreezeOrderApplyRequestDTO applyRequestDTO) {
        AccountBase accountBase = accountService.loadAccountById(applyRequestDTO.getAccountId());
        if (accountBase.getAvailableAmount().compareTo(applyRequestDTO.getAmount()) == -1) {
            throw new BizException("ACC7003");
        }
        String requestNo = lanMaoSequence.getRequestNo();
        FundsFreezeOrder fundsFreezeOrder = new FundsFreezeOrder();
        fundsFreezeOrder.setId(idWorker.nextId());
        fundsFreezeOrder.setRequestNo(requestNo);
        fundsFreezeOrder.setOrderId(applyRequestDTO.getOrderId());
        fundsFreezeOrder.setOrderType(applyRequestDTO.getFundsOrderTypeEnum().getType());
        fundsFreezeOrder.setUserId(accountBase.getUserId());
        fundsFreezeOrder.setAccountId(applyRequestDTO.getAccountId());
        fundsFreezeOrder.setPlatformUserNo(accountBase.getAccountNo());
        fundsFreezeOrder.setAmount(applyRequestDTO.getAmount());
        fundsFreezeOrder.setStatus(FundsFreezeOrderStatusEnum.STATUS_DEAL.getStatus());
        fundsFreezeOrder.setUnfreezeDegree(FundsUnfreezeDegreeEnum.DEGREE_UNFREEZE.getUnfreezeStatus());
        fundsFreezeOrder.setCreateTime(new Date());
        fundsFreezeOrder.setUpdateTime(new Date());
        freezeOrderMapperExt.insertSelective(fundsFreezeOrder);
        return fundsFreezeOrder;
    }

    /**
     * 更新冻结订单状态==成功
     * @param id
     * @return
     */
    @Transactional
    public void updateFreezeOrderSuccess(Long id) {

        FundsFreezeOrder freezeOrder = new FundsFreezeOrder();
        freezeOrder.setId(id);
        freezeOrder.setStatus(FundsFreezeOrderStatusEnum.STATUS_SUCCESS.getStatus());
        freezeOrder.setTransactionTime(new Date());
        freezeOrder.setUpdateTime(new Date());

        freezeOrderMapperExt.updateByPrimaryKeySelective(freezeOrder);
    }

    /**
     * 更新冻结订单状态==失败
     * @param id
     * @return
     */
    @Transactional
    public void updateFreezeOrderFail(Long id,String errorCode,String errorMsg) {
        FundsFreezeOrder freezeOrder = new FundsFreezeOrder();
        freezeOrder.setId(id);
        freezeOrder.setStatus(FundsFreezeOrderStatusEnum.STATUS_FAIL.getStatus());
        freezeOrder.setErrorCode(errorCode);
        freezeOrder.setErrorMessage(errorMsg);
        freezeOrder.setUpdateTime(new Date());

        freezeOrderMapperExt.updateByPrimaryKeySelective(freezeOrder);

    }

    /**
     * 根据请求流水号更新资金冻结订单(解冻更新解冻金额和状态)
     * @param requestNo
     * @param unfreezeAmount
     */
    @Transactional
    public void updateFundsFreezeOrderByRequestNo(String requestNo, BigDecimal unfreezeAmount) {
        FundsFreezeOrder fundsFreezeOrder = freezeOrderMapperExt.selectFreezeOrderByRequestNoForUpdate(requestNo);
        Assert.notNull(fundsFreezeOrder,"根据流水号未查询到冻结订单记录,请求流水号="+requestNo);

        FundsFreezeOrder order = new FundsFreezeOrder();
        order.setId(fundsFreezeOrder.getId());
        order.setUnfreezeAmount(fundsFreezeOrder.getUnfreezeAmount().add(unfreezeAmount));
        if(fundsFreezeOrder.getUnfreezeAmount().compareTo(fundsFreezeOrder.getAmount()) == 0) {
            order.setUnfreezeDegree(FundsUnfreezeDegreeEnum.DEGREE_ALL_UNFREEZE.getUnfreezeStatus());
        }else if(fundsFreezeOrder.getUnfreezeAmount().compareTo(fundsFreezeOrder.getAmount()) < 0) {
            order.setUnfreezeDegree(FundsUnfreezeDegreeEnum.DEGREE_PART_UNFREEZE.getUnfreezeStatus());
        }
        order.setUpdateTime(new Date());

        freezeOrderMapperExt.updateByPrimaryKeySelective(fundsFreezeOrder);
    }


    /**
     * 根据主键获取订单对象
     * @param id
     * @return
     */
    public FundsFreezeOrder selectByPrimaryKeyForUpdate(Long id) {
        return freezeOrderMapperExt.selectFreezeOrderByPrimaryKeyForUpdate(id);
    }

    public FundsFreezeOrder selectByPrimaryKey(Long id) {
        return freezeOrderMapperExt.selectByPrimaryKey(id);
    }

    /**
     * 查询成功的订单
     * @return
     */
    public FundsFreezeOrder queryFreezeOrderByRequestNo(String requestNo) {
        FundsFreezeOrder fundsFreezeOrder = freezeOrderMapperExt.selectFreezeOrderByRequestNo(requestNo);

        if(Objects.nonNull(fundsFreezeOrder) && fundsFreezeOrder.getStatus() == FundsFreezeOrderStatusEnum.STATUS_SUCCESS.getStatus()) {
            return fundsFreezeOrder;
        }
        return null;
    }

    /**
     * 根据订单id查询冻结记录
     * @param orderId
     * @param orderType
     * @return
     */
    public FundsFreezeOrder queryFreezeOrderByOrderId(Long orderId,Byte orderType) {
        FundsFreezeOrder fundsFreezeOrder =  freezeOrderMapperExt.selectFreezeOrderByOrderId(orderId,orderType);
        return fundsFreezeOrder;
    }

    /**
     * 查询处理中的冻结订单列表
     * @return
     */
    public List<FundsFreezeOrder> listFreezeOrderProcessing() {
        return freezeOrderMapperExt.listFreezeOrderList(FundsFreezeOrderStatusEnum.STATUS_DEAL.getStatus());
    }

}
